{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "95eb90ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import glob as gb\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "mpl.rcParams['figure.figsize'] = (16, 9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "00da2ad7",
   "metadata": {},
   "outputs": [],
   "source": [
    "PERF_DIR = Path('/Users/julien/Software/Others/OS-build-release/results/')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34ae2a1b",
   "metadata": {},
   "outputs": [],
   "source": [
    "csvs = list(PERF_DIR.glob('*.csv'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "421a5c23",
   "metadata": {},
   "outputs": [],
   "source": [
    "csv = csvs[0]"
   ]
  },
  {
   "cell_type": "raw",
   "id": "adb34632",
   "metadata": {},
   "source": [
    "csvs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "11286b85",
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_skip_rows(results_file: Path) -> int:\n",
    "    \"\"\"\n",
    "    Open the result benchmark, and locate the actual start of the timings\n",
    "\n",
    "    Returns:\n",
    "    --------\n",
    "    skiprows (int): the number of lines to skip when read_csv is called\n",
    "    \"\"\"\n",
    "    skiprows = 0\n",
    "    search_str = 'name,iterations,'\n",
    "    with open(results_file, 'r') as f:\n",
    "        content = f.read()\n",
    "    if search_str not in content:\n",
    "        return None\n",
    "    lines = content.splitlines()\n",
    "    while (search_str not in lines[skiprows]):\n",
    "        skiprows += 1\n",
    "\n",
    "    return skiprows"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "52c175ce",
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_bench_results(results_file: Path) -> pd.DataFrame:\n",
    "    skiprows = find_skip_rows(csv)\n",
    "    if skiprows is None:\n",
    "        return None\n",
    "    df = pd.read_csv(csv, skiprows=skiprows, index_col=0)\n",
    "    df = df.loc[df['iterations'].notnull()]\n",
    "    # Convert everything in ms\n",
    "    for col in ['real_time', 'cpu_time']:\n",
    "        df[col] = (df[[col, 'time_unit']].apply(\n",
    "            lambda row: pd.to_timedelta(arg=row[0], unit=row[1]), axis=1)\n",
    "                   .dt.total_seconds() * 1e3)\n",
    "        \n",
    "    return df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0ead991f",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_dict = {}\n",
    "dfs = []\n",
    "for csv in csvs:\n",
    "    fname = csv.name\n",
    "    #if 'Model_ModelObjects' in fname:\n",
    "    #    fname = 'Model_ModelObjects'\n",
    "    prefix  = Path(csv).name.split('_')[0]\n",
    "    test = '_'.join(fname.split('_')[1:-1])\n",
    "    \n",
    "    df = read_bench_results(csv)\n",
    "    if df is None:\n",
    "        continue\n",
    "    df['test_file'] = test\n",
    "    df['prefix'] = prefix\n",
    "    dfs.append(df)\n",
    "    \n",
    "df = pd.concat(dfs, axis=0)\n",
    "df.set_index(['prefix', 'test_file'], append=True, inplace=True)\n",
    "df_real = df['real_time'].unstack('prefix')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d809044",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real[df_real['moveAllModelResizeAndLoop'].notnull()].sum(axis=0).sort_values()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9d1e8b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_sum = df_real[df_real['moveAllModelResizeAndLoop2'].notnull()].groupby('test_file').sum()\n",
    "df_sum['orim'] = df_sum[['ori', 'ori2']].mean(axis=1)\n",
    "df_sum[['orim', 'move1', 'move2', 'move3', 'moveAll', 'moveAll2', 'moveAllModelResizeAndLoop', 'moveAllModelResizeAndLoop2']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f08007c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8abd6fa7",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_byfile = df_sum[['orim', 'moveAll', 'moveAll2', 'moveAllModelResizeAndLoop', 'moveAllModelResizeAndLoop2']].groupby('test_file').sum()\n",
    "\n",
    "(df_byfile.divide(df_byfile['orim'], axis=0) - 1).style.format('{:.2%}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9363b09c",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_sum[['orim', 'moveAllModelResizeAndLoop', 'moveAllModelResizeAndLoop2']].groupby('test_file').sum().pct_change(axis=1).iloc[:, 1:].style.format('{:.2%}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25f6359e",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real.swaplevel(0, 1, axis=0).loc['Model', ['ori', 'ori2', 'moveAll', 'moveAll2', 'moveAllModelResizeAndLoop2']].plot(kind='barh')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d54fae1e",
   "metadata": {},
   "source": [
    "# Plot the interesting stuff that is size dependent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9e47865a",
   "metadata": {},
   "outputs": [],
   "source": [
    "cols = ['ori', 'ori2', 'moveAll', 'moveAll2', 'moveAllModelResizeAndLoop2']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fb5a3c3",
   "metadata": {},
   "outputs": [],
   "source": [
    "test_files = ['ThermalZoneCombineSpaces', 'Model_ModelObjects', 'Model',\n",
    "         'Vector_remove_vs_copy', 'Workspace', 'ForwardTranslator']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "80704904",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "for test_file in test_files:\n",
    "    toplot = df_real.swaplevel(0, 1, axis=0).loc[test_file, cols]\n",
    "    toplot.index = toplot.index.str.split('/', expand=True)\n",
    "    toplot.index = toplot.index.set_levels(level=1, levels=toplot.index.levels[1].astype(int))\n",
    "    names = ['Test', 'N']\n",
    "    groupby = ['Test']\n",
    "    if test_file == 'ForwardTranslator':\n",
    "        toplot.index = toplot.index.set_levels(level=2, levels=toplot.index.levels[2].astype(int).astype(bool))\n",
    "        names.insert(-1, 'ExcludeSpaceTranslation')\n",
    "        groupby.append('ExcludeSpaceTranslation')\n",
    "        toplot.index = toplot.index.swaplevel(-1, 1)\n",
    "    toplot.index.names = names\n",
    "    \n",
    "    toplot.sort_index(inplace=True)\n",
    "    #toplot.plot(kind='barh')\n",
    "\n",
    "    grouped = toplot.groupby(groupby)\n",
    "\n",
    "    ncols = 1\n",
    "    nrows = int(np.ceil(grouped.ngroups/ncols))\n",
    "\n",
    "    fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(16, nrows*5), sharey=False)\n",
    "\n",
    "    for (key, ax) in zip(grouped.groups.keys(), axes.flatten()):\n",
    "        grouped.get_group(key).loc[key].plot(ax=ax)\n",
    "        title = f'{test_file}'\n",
    "        if isinstance(key, str):\n",
    "            key = [key]\n",
    "        for k,v in zip(groupby, key):\n",
    "            title += f', {k}={v}'\n",
    "        ax.set_title(title)\n",
    "\n",
    "    ax.legend()\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdd263bc",
   "metadata": {},
   "source": [
    "# Plot categorical stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e33b252e",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f017eb73",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real.swaplevel(0, 1, axis=0).loc['VersionTranslation', cols]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a5f74612",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real.index.get_level_values(1).unique()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a675a85b",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "toplot = df_real.swaplevel(0, 1, axis=0).loc[test_files, cols]\n",
    "toplot.plot(kind='barh', figsize=(16, 0.75*toplot.shape[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0cde441a",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "test_files = ['LoadIdfFile', 'VersionTranslation', 'IdfObjectParse', 'LoadIdd']\n",
    "test_file = test_files[0]\n",
    "for test_file in test_files:\n",
    "    print(test_file)\n",
    "    toplot = df_real.swaplevel(0, 1, axis=0).loc[test_file, cols]\n",
    "    toplot.index = toplot.index.str.split('/', expand=True)\n",
    "    if toplot.index.nlevels > 1 and toplot.index.levels[0].size == 1:\n",
    "        toplot.index = toplot.index.droplevel(level=0)\n",
    "    if toplot.index.nlevels > 1 and toplot.index.levels[1].size == 1:\n",
    "        toplot.index = toplot.index.droplevel(level=1)\n",
    "    if toplot.index.nlevels > 1:\n",
    "        raise\n",
    "        \n",
    "    fig, ax = plt.subplots(figsize=(16, 1*toplot.shape[0]))\n",
    "    toplot.plot(kind='barh', ax=ax)\n",
    "    ax.set_title(test_file)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6d7eb83",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a8cbdb9",
   "metadata": {},
   "outputs": [],
   "source": [
    "toplot.plot(kind='barh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "071f557b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "93aa120a",
   "metadata": {},
   "outputs": [],
   "source": [
    "toplot.plot(kind='barh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f03e51c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "names = ['Test', 'N']\n",
    "groupby = ['Test']\n",
    "if test_file == 'ForwardTranslator':\n",
    "    toplot.index = toplot.index.set_levels(level=2, levels=toplot.index.levels[2].astype(int).astype(bool))\n",
    "    names.insert(-1, 'ExcludeSpaceTranslation')\n",
    "    groupby.append('ExcludeSpaceTranslation')\n",
    "    toplot.index = toplot.index.swaplevel(-1, 1)\n",
    "toplot.index.names = names\n",
    "\n",
    "toplot.sort_index(inplace=True)\n",
    "#toplot.plot(kind='barh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "989458ef",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real.swaplevel(0, 1, axis=0).loc['ThermalZoneCombineSpaces', ['ori', 'ori2', 'moveAll', 'moveAll2', 'moveAll2b']].plot(kind='barh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb64cb96",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "187a2d9f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d4870a4d",
   "metadata": {},
   "outputs": [],
   "source": [
    "100*(toplot.max(axis=1).divide(toplot.min(axis=1)) - 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b50a9a31",
   "metadata": {},
   "outputs": [],
   "source": [
    "toplot.agg(['min', 'max'], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cc2f1356",
   "metadata": {},
   "outputs": [],
   "source": [
    "toplot = df_real.swaplevel(0, 1, axis=0).loc[\n",
    "    'ForwardTranslator',\n",
    "#    'ThermalZoneCombineSpaces',\n",
    "    [x for x in df_real.columns if\n",
    "     #'ori' in x or\n",
    "     'moveAll2' in x]]\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(16, 16))\n",
    "(100*(toplot.divide(toplot.mean(axis=1), axis=0) - 1)).plot(kind='barh', ax=ax)\n",
    "ax.xaxis.set_major_formatter(mpl.ticker.PercentFormatter())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab30426f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f031dda3",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real.index.tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d7884bb4",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real.swaplevel(0, 1, axis=0).loc['Model', ['ori', 'ori2', 'moveAll', 'moveAll2']].plot(kind='barh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c8da6c98",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "grouped = df_real['ori', 'moveAll', 'moveAll2']].groupby('test_file')\n",
    "\n",
    "ncols = 1\n",
    "nrows = int(np.ceil(grouped.ngroups/ncols))\n",
    "\n",
    "fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(16, nrows*4), sharey=False)\n",
    "\n",
    "for (key, ax) in zip(grouped.groups.keys(), axes.flatten()):\n",
    "    grouped.get_group(key).plot(kind='barh', ax=ax)\n",
    "\n",
    "ax.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34dc7261",
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "df_real.plot(figsize=(16, 9))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18393c67",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "237730ed",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real['orim'] = df_real[['ori', 'ori2']].mean(axis=1)\n",
    "df_real['newm'] = df_real[['new'\n",
    "                           #, 'new2'\n",
    "                          ]].mean(axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2e147ab2",
   "metadata": {},
   "outputs": [],
   "source": [
    "(df_real[['orim', 'newm']]).pct_change(axis=1)['newm'].sort_values().plot(kind='barh', figsize=(16, 36))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58f7ab17",
   "metadata": {},
   "outputs": [],
   "source": [
    "(df_real['newm'] - df_real['orim']).sort_values().plot(kind='barh', figsize=(16, 9))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b9b0d19",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a9f0d9f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real[['orim', 'newm']].plot(kind='barh', figsize=(16, 36))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7bd8b9e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_real[['orim', 'newm']].mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73424f07",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.9"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
